﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
//int main()
//{
//	int a[3][4] = { 0 };
//	printf("%zd\n", sizeof(a));
//	//sizeof(数组名)，计算的是整个数组的大小，3*4*sizeof(int) = 48
//
//	printf("%zd\n", sizeof(a[0][0]));
//	//计算的是第一个数组元素的大小 -- 4
//
//	printf("%zd\n", sizeof(a[0]));
//	//a[0] 表示的是第一行的数组名，计算的是第一行的数组的大小 --- 16
//
//	printf("%zd\n", sizeof(a[0] + 1));
//	//数组名表示首元素的地址 -- 第一行第一个元素的地址 -- +1 跳到第二个元素 -- 求的还是地址 4/8
//
//	printf("%zd\n", sizeof(*(a[0] + 1)));
//	//第一行第二个元素的大小  -- 4
//
//	printf("%zd\n", sizeof(a + 1));
//	//数组名没有单独放在sizeof中，所以a表示首元素的地址 -- 第一行的地址 -- a+1 跳过第一行是第二行的地址 -- 4/8
//
//	printf("%zd\n", sizeof(*(a + 1)));
//	//1.a+1是第二行的地址 -- int(*)[4] -- *(a+1) -- 拿到的就是第二行 -- 16
//	//2.*(a+1) -- a[1]  sizeof(a[1]) -- 数组单独放在sizeof中，计算的是第二行数组的大小
//
//	printf("%zd\n", sizeof(&a[0] + 1));
//	//a[0]是第一行的数组名,&a[0] 取出的是第一行的地址，&a[0]+1就是第二行的地址，求的还是地址 -- 4/8
//
//	printf("%zd\n", sizeof(*(&a[0] + 1)));
//	//第二行的地址解引用就是第二行   -- 16
//
//	printf("%zd\n", sizeof(*a));
//	//a表示首元素的地址 ， 就是第一行的地址 ，*a就是第一行 ， 计算的是第一行的大小  --  16
//	//*（a） = *(a+0) -- a[0]
//
//	printf("%zd\n", sizeof(a[3]));
//	//sizeof里的表达式是不会参与计算的 -- 表达式一旦写出来，它的类型就已经确定了
//	// -- 不存在越界 -- 因为不会真实的访问内存，仅通过推导，就可以知道长度
//	
//	printf("%zd\n", sizeof(int));
//	return 0;
//}

//int main()
//{
//	int a[5] = { 1, 2, 3, 4, 5 };
//	int* ptr = (int*)(&a + 1);
//	printf("%d,%d", *(a + 1), *(ptr - 1));
//	return 0;
//	//程序的结果是什么？
//}

//指针+-整数跳过多少个字节，取决于类型
//struct Test
//{
//	int Num;
//	char* pcName;
//	short sDate;
//	char cha[2];
//	short sBa[4];
//}*p = (struct Test*)0x100000;
//int main()
//{
//	printf("%p\n", p + 0x1);//0x100014
//	printf("%p\n", (unsigned long)p + 0x1);//0x100001  整型+1就是+1
//	printf("%p\n", (unsigned int*)p + 0x1);//0x100004
//	return 0;
//}

//int main()
//{
//	int a[3][2] = { (0, 1), (2, 3), (4, 5) };
//
//	int* p;
//	p = a[0];
//	printf("%d", p[0]);
//	return 0;
//}

//int main()
//{
//	int a[5][5];
//	int(*p)[4];
//	p = a;
//	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
//	return 0;
//}

//int main()
//{
//	int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//	int* ptr1 = (int*)(&aa + 1);
//	int* ptr2 = (int*)(*(aa + 1));
//	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
//	return 0;
//}

//int main()
//{
//	char* a[] = { "work","at","alibaba" };
//	char** pa = a;
//	pa++;
//	printf("%s\n", *pa);
//	return 0;
//}

//int main()
//{
//	char* c[] = { "ENTER","NEW","POINT","FIRST" };
//	char** cp[] = { c + 3,c + 2,c + 1,c };
//	char*** cpp = cp;
//	printf("%s\n", **++cpp);
//	printf("%s\n", *-- * ++cpp + 3);
//	printf("%s\n", *cpp[-2] + 3);
//	printf("%s\n", cpp[-1][-1] + 1);
//	return 0;
//}

//判断是否是小写
//#include <ctype.h>
//int main()
//{
//	int ret = islower('x');
//	if (ret)
//		printf("小写\n");
//	else
//		printf("大写\n");
//	return 0;
//}

//字符串中的⼩写字⺟转⼤写，其他字符不变
//#include <ctype.h>
//int main()
//{
//	char arr[] = "hello,I am a Student.";
//	int i = 0;
//	while (arr[i])
//		//遍历到\0 时候，ASCLL码值为0，停止遍历
//	{
//		if (islower(arr[i]))
//		{
//			arr[i] -= 32;
//		}
//		i++;
//	}
//	printf("%s\n", arr);
//	return 0;
//}

//#include <ctype.h>
//int main()
//{
//	printf("%c\n", toupper('a'));
//	printf("%c\n", tolower('A'));
//	return 0;
//}

//#include <string.h>
//int main()
//{
//	char arr[] = "abcdef";
//	//a b c d e f \0
//	size_t len = strlen(arr);
//	printf("%zd\n", len);
//	return 0;
//}
////strlen 从给定的起始位置开始，向后统计\0 之前的字符个数

//#include <string.h>
//int main()
//{
//	char arr1[] = "abcdef";
//	char arr2[] = "abc";
//	//         3     -     6
//	//两个size_t的值相减也是size_t , 在数学上，我们算出的-3 被当成了无符号数了
//	//-3
//	//10000000 00000000 00000000 00000011  原码
//	//11111111 11111111 11111111 11111100  反码
//	//11111111 11111111 11111111 11111101  补码
//	//可是size_t 中会把补码看成原码 ， 那么我们的-3 在size_t 型中，是非常大的！
//	if (strlen(arr2) - strlen(arr1) > 0)
//	//	if (strlen(arr2) > strlen(arr1) )
//	//	if ((int)strlen(arr2) - (int)strlen(arr1) > 0)
//		printf(">\n");
//	else
//		printf("<\n");
//	return 0;
//}

//strlen的模拟实现
//#include <assert.h>
//size_t my_strlen(const char* str)
//{
//	size_t count = 0;
//	assert(str != NULL);
//	while (*str)
//	{
//		count++;
//		str++;
//	}
//	return count;
//}
//int main()
//{
//	char arr[] = "abcdef";
//	size_t len = my_strlen(arr);
//	//使用size_t是因为计算字符串的长度时，不会有负值，int 是有符号型，size_t是无符号型
//	printf("%zd\n", len);
//	return 0;
//}

//练习2
//#include <assert.h>
//size_t my_strlen(const char* str)
//{
//	size_t count = 0;
//	assert(str != NULL);
//	while (*str)
//	{
//		count++;
//		str++;
//	}
//	return count;
//}
//int main()
//{
//	char arr[] = "abcdef";
//	size_t len = my_strlen(arr);
//	printf("%zd\n", len);
//	return 0;
//}

//指针 - 指针
//#include <assert.h>
//size_t my_strlen(const char* str)
//{
//	char* strat = str;
//	assert(str != NULL);
//	while (*str)
//	{
//		str++;
//	}
//	return str - strat;
//}
//int main()
//{
//	char arr[] = "abcdef";
//	size_t len = my_strlen(arr);
//	printf("%zd\n", len);
//	return 0;
//}

//递归的方式 -- 大事化小
int main()
{

	return 0;
}